#include "StdAfx.h"
#include "AnimationInstance.h"
#include "Animation.h"
#include "Utility\ColladaFile.h"

AnimationInstance::AnimationInstance(Animation* pAnimation)
{
	m_pAnimation = pAnimation;
	m_fElaspedTime = 0.0f;
	m_bPlaying = true;
	m_aBoneTransformations.SetSize(MAX_BONES);	
}

AnimationInstance::~AnimationInstance(void)
{
}

bool AnimationInstance::Update(float fDeltaTime)
{	
	if( !m_bPlaying )
		return false;

	m_fElaspedTime += fDeltaTime;	
	bool bFinished = true;

	//get transformation
	for(int i = 0; i < m_pAnimation->BoneCount(); i++)
	{			
		FixedArray<float>* pTimes = m_pAnimation->GetTimes(i);
		FixedArray<Matrix>* pTransforms = m_pAnimation->GetTransforms(i);

		Matrix mCurrent, mPrev, mParent;
		mCurrent.Identity();// = m_pAnimation->GetBindPose(i);
		mPrev.Identity();
		mParent.Identity();		

		//See if this bone has any transformations		
		int iCurrentKey = 0;
		float fNextKey = 0.0f;
		float fPrevKey = 0.0f;

		//see which key we are at
		for(int j = 0; j < pTimes->GetNumElementsUsed(); j++)
		{
			fNextKey = (*pTimes)[j];
			if( m_fElaspedTime <  fNextKey )
			{
				iCurrentKey = j;
				bFinished = false;
				break;
			}
			fPrevKey = fNextKey;
		}	

		//if the animation is not finished interpolate to the current matrix
		if( !bFinished )
		{
			mCurrent = (*pTransforms)[iCurrentKey];	
			if( iCurrentKey > 0 )
			{
				//get all the matricies					
				mPrev = (*pTransforms)[iCurrentKey - 1];
				float fTime = (m_fElaspedTime - fPrevKey) / (fNextKey - fPrevKey);

				mCurrent = mPrev + ( (mCurrent - mPrev) * fTime);
			}
			m_bPlaying = true;
		}
		else
		{
			//last key of animation
			mCurrent = (*pTransforms)[pTransforms->GetNumElementsUsed() - 1];	
			m_bPlaying = false;
			//m_fElaspedTime -= fNextKey;
		}
			

		//try and find the parent matrix
		int iParent = m_pAnimation->GetBoneParent(i);	
		if( iParent > -1 )
			mParent = m_aBoneTransformations[iParent];
		
		Matrix bone = mCurrent * mParent;	
		m_aBoneTransformations[i] = bone;
		/*Matrix inv = m_pAnimation->GetInvBind(i);
		Matrix mFinal = inv * bone;
		m_aFinalTransformations[i] = mFinal;*/
	}	

	return true;
}